﻿/*
This project and all of its code is/are Copyright (C) 2017  Nils Hunter Alving

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
using DynamicDependencyContainer.Interfaces;
using System;

namespace DynamicDependencyContainer.Models
{
    /// <summary>
    /// Allows registration of a type to represent an interface, using the singleton pattern.
    /// The singleton is not created until the first time it is requested
    /// </summary>
    public class LazyInstanceRegisteredType<T> : RegisteredType<T>  where T : class
    {
        private T _instance;
        protected override T Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = CreateObject();
                }
                return _instance;
            }

            set
            {
                _instance = value;
            }
        }

        /// <summary>
        /// Registers the specified class as the type to be used to represent the specified interface, using the singleton pattern.
        /// </summary>
        /// <param name="interfaceImplemented">The interface that is being registered</param>
        /// <param name="implementingClass">The class that implements the interface</param>
        /// <param name="dependencyResolver">The object that will be used to resolve dependencies when the Resolve() method is invoked</param>
        public LazyInstanceRegisteredType(Type interfaceImplemented, Type implementingClass, IResolveDependencies dependencyResolver) 
            : base(interfaceImplemented, implementingClass, dependencyResolver)
        {
        }
        ///<summary>
        /// Registers the specified class as the type to be used to represent the specified interface, using the singleton pattern.
        /// </summary>
        /// <param name="interfaceImplemented">The interface that is being registered</param>
        /// <param name="implementingClass">The class that implements the interface</param>
        /// <param name="constructorArguments">The arguments to be passed to the constructor when the singleton is created</param>
        /// <param name="dependencyResolver">The object that will be used to resolve dependencies when the Resolve() method is invoked</param>
        public LazyInstanceRegisteredType(Type interfaceImplemented, Type implementingClass, object[] constructorArguments, IResolveDependencies dependencyResolver) 
            : base(interfaceImplemented, implementingClass, constructorArguments, dependencyResolver)
        {
        }
        ///<summary>
        /// Registers the specified class as the type to be used to represent the specified interface, using the singleton pattern.
        /// </summary>
        /// <param name="interfaceImplemented">The interface that is being registered</param>
        /// <param name="implementingClass">The class that implements the interface</param>
        /// <param name="initializationFunction">An intialization delegate that will be invoked after the object is constructed. 
        /// The object being constructed will be passed to the delegate as a parameter</param>
        /// <param name="dependencyResolver">The object that will be used to resolve dependencies when the Resolve() method is invoked</param>
        public LazyInstanceRegisteredType(Type interfaceImplemented, Type implementingClass, Action<T> initializationFunction, IResolveDependencies dependencyResolver)
            : base(implementingClass, initializationFunction, dependencyResolver)
        {
        }
        ///<summary>
        /// Registers the specified class as the type to be used to represent the specified interface, using the singleton pattern.
        /// </summary>
        /// <param name="interfaceImplemented">The interface that is being registered</param>
        /// <param name="implementingClass">The class that implements the interface</param>
        /// <param name="initializationFunction">An intialization delegate that will be invoked after the object is constructed. 
        /// The object being constructed will be passed to the delegate as a parameter</param>
        /// <param name="constructorArguments">The arguments to be passed to the constructor when the singleton is created</param>
        /// <param name="dependencyResolver">The object that will be used to resolve dependencies when the Resolve() method is invoked</param>
        public LazyInstanceRegisteredType(Type interfaceImplemented, Type implementingClass, Action<T> initializationFunction, object[] constructorArguments, IResolveDependencies dependencyResolver) 
            : base(implementingClass, initializationFunction, constructorArguments, dependencyResolver)
        {
        }
    }
}
